package db.mongo;

import com.mongodb.*;

import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @fileName: MongoDao
 * @author: Han
 * @date: 2018/5/29 9:40
 * @dscription: TODO
 */
public class MongoDao {
    /**
     * MongoDB接口单例
     */
    private static final MongoDao MONGO_DAO = new MongoDao();
    /**
     * MongoDB数据库实例
     */
    private MongoClient mongoClient = null;

    /**
     * 实例化MongoClient
     */
    private MongoDao() {
        if (Objects.isNull(mongoClient)) {
            MongoClientOptions.Builder builder = new MongoClientOptions.Builder();
            //与目标数据库能够建立的最大连接数为50
            builder.connectionsPerHost(50);
            //自动重连
            builder.autoConnectRetry(true);
            //允许阻塞倍数
            builder.threadsAllowedToBlockForConnectionMultiplier(30);
            //获取到可用连接之前最大等待2分钟
            builder.maxWaitTime(1000 * 60 * 2);
            //建立连接的timeout设置为1分钟
            builder.connectTimeout(1000 * 60);
            MongoClientOptions options = builder.build();
            try {
                List<ServerAddress> addressList = new ArrayList<>();
                ServerAddress address1 = new ServerAddress("192.168.11.234", 10005);
                addressList.add(address1);
                //连接实例
                mongoClient = new MongoClient(addressList, options);
            } catch (MongoException | UnknownHostException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取MongoDao实例
     *
     * @return MongoDao实例
     */
    public static MongoDao getMongoDaoInstance() {
        return MONGO_DAO;
    }

    /**
     * 使用指定参数查询指定表数据
     *
     * @param dbName  库名
     * @param colName 表明
     * @param keys    键名
     * @param values  值名
     * @return 记录
     */
    public List<DBObject> find(String dbName, String colName, int num, String[] keys, Object[] values)throws Exception{

        List<DBObject> resultList = new ArrayList<>();
        DB db = null;
        DBCollection dbCollection;
        DBCursor cursor = null;

        if (Objects.isNull(keys) && Objects.isNull(values)) {
            throw new IllegalArgumentException("键值均不能为空");
        }
        if (keys.length == values.length) {
            try {
                //获取指定库连接
                db = mongoClient.getDB(dbName);
                //获取数据库中指定的collection集合
                dbCollection = db.getCollection(colName);
                // 构建查询条件
                BasicDBObject queryObj = new BasicDBObject();
                // 填充查询条件
                for (int i = 0; i < keys.length; i++) {
                    queryObj.put(keys[i], values[i]);
                }
                // 获取查询的游标
                cursor = dbCollection.find(queryObj);
                cursor.addOption(Bytes.QUERYOPTION_NOTIMEOUT);
                //循环获取查询数据
                int count = 0;
                while ((num < 0 || count < num) && cursor.hasNext()) {
                    resultList.add(cursor.next());
                    count++;
                }
            } catch (Exception e) {
                //出现异常,先关闭连接,再抛出异常
                Objects.requireNonNull(cursor).close();
                Objects.requireNonNull(db).requestDone();
                throw new Exception();
            } finally {
                Objects.requireNonNull(cursor).close();
                Objects.requireNonNull(db).requestDone();
            }
        } else {
            throw new IllegalArgumentException("键值长度不一致");
        }
        return resultList;
    }
}
